﻿using System.Collections;
using System.Collections.Generic;
using UnityEngine;

/// <summary>
/// smp == ShadowMapProject
/// </summary>
public class SMPShadowMap : MonoBehaviour
{
    public bool IsAutoRotate;
    public RenderTexture m_ShadowRT;
    public Camera m_LightCamera;
    public Shader m_ShadowMap;
    public GameObject m_Light;

    [Range(0.0f, 1.0f)]
    public float shadowColor = 0.0f;

    [Range(0.0f, 1.0f)]
    public float shadowBias = 0.0f;

    [Range(0.0f, 1.0f)]
    public float shadowNormalBias = 0.0f;

    private void Start()
    {
        m_ShadowRT = null;
        m_LightCamera = null;

        CreateOrthographicCamera();
    }

    private void CreateOrthographicCamera()
    {
        GameObject objCamera = new GameObject("LightCamera");
        objCamera.transform.parent = gameObject.transform;
        objCamera.transform.localPosition = Vector3.zero;
        objCamera.transform.rotation = new Quaternion(0, 0, 0, 0);
        m_LightCamera = objCamera.AddComponent<Camera>();
        m_LightCamera.clearFlags = CameraClearFlags.SolidColor;
        m_LightCamera.backgroundColor = Color.white;
        m_LightCamera.orthographic = true;
        m_LightCamera.orthographicSize = 8;
        m_LightCamera.nearClipPlane = 0.3f;
        m_LightCamera.farClipPlane = 30.0f;
        m_LightCamera.depth = -1;
        //m_LightCamera.enabled = false;
        //m_LightCamera.cullingMask = 1 << LayerMask.NameToLayer("caster");

        m_ShadowRT = new RenderTexture(1024, 1024, 24, RenderTextureFormat.RFloat);
        m_ShadowRT.hideFlags = HideFlags.DontSave;
        m_ShadowRT.filterMode = FilterMode.Point;

        if (!m_LightCamera.targetTexture)
            m_LightCamera.targetTexture = m_ShadowRT;

        m_LightCamera.SetReplacementShader(m_ShadowMap, "RenderType");
    }

    private void LateUpdate()
    {
        if(IsAutoRotate)
            m_Light.transform.RotateAround(Vector3.zero, new Vector3(0, 1, 0), Time.deltaTime * 10.0f);

        
        Shader.SetGlobalTexture("_gShadowMapTexture", m_ShadowRT);
        Shader.SetGlobalFloat("_gShadowBias", shadowBias);
        Shader.SetGlobalFloat("_gShadowNormalBias", shadowNormalBias);
        //VP矩阵（projectionMatrix），是将相机空间中的点从视锥体(frustum)变换到规则观察体(Canonical View Volume)中
        //实际上也就是3d->2d，世界坐标，转视线贴图
        Matrix4x4 projectionMatrix = GL.GetGPUProjectionMatrix(m_LightCamera.projectionMatrix, false) * m_LightCamera.worldToCameraMatrix;
        Shader.SetGlobalMatrix("_gWorldToShadow", projectionMatrix);
        Shader.SetGlobalFloat("_gShadowStrength", shadowColor);
    }

    private void OnApplicationQuit()
    {
        m_LightCamera.ResetReplacementShader();
    }
}
